/* -*- Mode:Prolog; coding:ISO-8859-1; -*- */



:- use_module(library(lists)).
:- use_module(library(random)).

:- ensure_loaded([sicstus_support]). 

:- multifile test/2.
:- discontiguous test/2.


:-if(current_prolog_flag(dialect, sicstus)).
:- use_module(library(sets)).
:-endif.



remove_duplicates_with_dontuseme(In, Out) :-
        reverse(In, RIn),
        x_remove_duplicates_with_dontuseme(RIn, ROut),
        reverse(ROut, Out).

x_remove_duplicates_with_dontuseme([], []).

x_remove_duplicates_with_dontuseme([H|T], [dontuseme | T1]) :-
        member_var(H, T), !,
        x_remove_duplicates_with_dontuseme(T, T1).

x_remove_duplicates_with_dontuseme([H|T], [H | T1]) :-
        x_remove_duplicates_with_dontuseme(T, T1).

        test(remove_duplicates/2, Outcome) :-
                (remove_duplicates_cstm([a, A, B, a], [A, B, a]  ) ->
                        Outcome = true ; Outcome = false).

remove_duplicates_cstm([], []).

remove_duplicates_cstm([H|T], T1) :-
        member_var(H, T), !,
        remove_duplicates_cstm(T, T1).

remove_duplicates_cstm([H|T], [H | T1]) :-
        remove_duplicates_cstm(T, T1).

member_var(M, [H | _T]) :-
        M == H, !.

member_var(M, [_H | T]) :-
        member_var(M, T).


/*
list2conjunction(List,Conjunction)
*/
list2conjunction([],true) :- !.
list2conjunction(List,Conjunction):-
        var(List) ->
                (\+(var(Conjunction)), Conjunction=(A,B) ->
                         list2conjunction(ListA,A),
                         list2conjunction(ListB,B),
                         union(ListA,ListB,List);
                 List=[Conjunction]);
        List=[X] ->
                Conjunction=X;
        List=[X,Y|Rest] ->
                list2conjunction([Y|Rest],ConjunctionR),
                Conjunction=(X,ConjunctionR).

:-if(current_prolog_flag(dialect, yap)).
  union( [ ], X, X ).
  union( [ X | R ], Y, Z ) :- 
     member( X, Y ),
     !,
     union( R, Y, Z ).
  union( [ X | R ], Y, [ X | Z ] ) :- union( R, Y, Z ).
:-endif.



subtract_c([], _, []) :- !.
subtract_c([A|C], B, D) :-
        memberchk(A, B), !,
        subtract(C, B, D).
subtract_c([A|B], C, [A|D]) :-
        subtract(B, C, D).


concat_atoms(A1, A2, C) :-
        name(A1, SA1),
        name(A2, SA2),
        append(SA1, SA2, SC),
        name(C, SC).


no_duplicates([]).
no_duplicates([H |T]) :-
        \+ member(H, T),
        no_duplicates(T).


%UNION
mymember(X,[X|_]) :- !.
mymember(X,[_|T]) :- mymember(X,T).



set([],[]).
set([H|T],[H|Out]) :-
    \+ mymember(H,T),
    set(T,Out).
set([H|T],Out) :-
    mymember(H,T),
    set(T,Out).

un(X, Y, Z) :- append(X, Y, W), set(W,Z).







% rnd_select(+L,+N,-R)
%       (list,integer,list)
%       the list R contains N randomly selected 
%       items taken from the list L.

rnd_select(_,0,[]).
rnd_select(Xs,N,[X|Zs]) :- N > 0,
    length(Xs,L),
    random(1, L, RL),
    I is RL,
    remove_at(X,Xs,I,Ys),
    N1 is N - 1,
    rnd_select(Ys,N1,Zs).

% rnd_select(+L,+N,-R, -Rest)
%       (list,integer,list)
%       the list R contains N randomly selected 
%       items taken from the list L. Rest gives what's left

rnd_select(R,0,[],R).
rnd_select(Xs,N,[X|Zs],R) :- N > 0,
    length(Xs,L),
    random(1, L, RL), 
    I is RL,
    remove_at(X,Xs,I,Ys),
    N1 is N - 1,
    rnd_select(Ys,N1,Zs,R).


% remove_at(X,L,K,R)
% (element,list,integer,list) 
%       X is the K'th element of the list L; R is the
%       list that remains when the K'th element is removed from L.

remove_at(X,[X|Xs],1,Xs).
remove_at(X,[Y|Xs],K,[Y|Ys]) :- K > 1, 
   K1 is K - 1, remove_at(X,Xs,K1,Ys).



append_all([], []).

append_all([H|T], Out) :-
        append_all(T, OutLoc),
        append(H, OutLoc, Out).
